package cn.tedu.note.aop;

import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javax.annotation.PostConstruct;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 * 性能审计 切面组件
 */
@Component
@Aspect
public class TimerAspect {
	//管理一个文件, 和一个阻塞队列
	private File file;
	//从配置文件config中获取 logfile 属性
	//添加一个配置文件 config.properties
	//配置文件中包含属性 logfile
	//spring中读取配置文件为Bean config
	@Value("#{config.logfile}")
	public void setFilename(String filename){
		System.out.println(filename); 
		file = new File(filename);
	}
	
	//创建阻塞队列
	private BlockingQueue<String> queue=
		new LinkedBlockingQueue<String>(500);
	
	//切入到全部业务方法的前后, 进而计算时间消耗
	@Around("bean(*Service)")
	public Object test(
		ProceedingJoinPoint joinPoint)
		throws Throwable {
		long t1=System.currentTimeMillis();
		//调用业务方法
		Object obj = joinPoint.proceed();
		long t2=System.currentTimeMillis();
		//计算业务方法消耗时间
		long t=t2-t1;
		//获取当前的线程(Tomcat创建的线程)
		Thread tx = Thread.currentThread();
		System.out.println(tx+":"+t); 
		//Thread.sleep(5000);
		//得到了 时间, 
		//得到方法签名
		Signature s=joinPoint.getSignature();
		//将需要保存的数据添加到队列中
		String str=tx+","+s+","+t;
		//将需要保存的数据添加到队列中
		queue.offer(str);
		return obj;
	}
	
	//@PostConstruct 声明的方法在Bean对象创建以后
	// 后立即执行
	@PostConstruct
	//创建Bean组件以后立即执行的方法
	public void start(){
		//Bean组件TimerAspect以后立即启动线程
		t.start();
	}
	private Thread t = new Thread(){
		public void run() {
			System.out.println("Ok");
			try{
				while(true){
					//take从队列中取出一个数据
					//如果没有数据, 则等到有数据为止
					String s = queue.take();
					//打开文件(追加方式)
					PrintWriter out= new PrintWriter(new FileOutputStream(file, true));
					//写数据
					out.println(s);
					System.out.println("T:"+s);
					while(!queue.isEmpty()){
						//写数据
						s=queue.take();
						System.out.println("T:"+s);
						out.println(s);
					}
					//关闭文件
					out.close();
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		};
	};
}




